#ifndef TIMER_QUEUE_H_
#define TIMER_QUEUE_H_

#include <map>
#include <set>
#include <vector>

#include "netlib/base/noncopyable.h"
// #include "netlib/base/time_stamp.h"
#include "netlib/net/call_backs.h"
#include "netlib/net/event/channel.h"
#include "netlib/net/timer/timer_index.h"

namespace netlib::net {

class EventLoop;
class Timer;

class TimerQueue : NonCopyable {
public:
	explicit TimerQueue(EventLoop* loop);
	~TimerQueue();

	TimerIndex AddTimer(const TimerCallback& cb, Timestamp when, double interval);
	void Cancel(TimerIndex idx);

private:
	struct Compare {
		bool operator()(const TimerIndex& x, const TimerIndex& y) const {
			if (x.time_ == y.time_) {
				return x.sequence_ < y.sequence_;
			}
			return x.time_ < y.time_;
		}
	};

	using TimerMap = std::map<TimerIndex, Timer*, Compare>;
	using Entry = TimerMap::value_type;

	// typedef std::set<Entry> TimerSet;
	// typedef std::pair<Timer*, int64_t> ActivateTimer;
	// typedef std::set<ActivateTimer> ActivateTimerSet;
	bool Insert(Timer* timer);
	void CancelInLoop(TimerIndex idx);
	void AddTimerInLoop(Timer* timer);

	std::vector<Entry> GetExpired(Timestamp now);
	void Reset(const std::vector<Entry>& expired, Timestamp time);
	void HandleRead();

	bool is_calling_expired_;
	EventLoop* loop_;
	const int kTimerfd;
	Channel timer_channel_;
	TimerMap timers_;
	TimerMap cancels_;
	// ActivateTimerSet cancel_timers_;
};

} // namespace netlib::net

#endif // TIMER_QUEUE_H_